#import "Controller.h"
#import "PreviewView.h"
#import "AKImageKit.h"

@implementation Controller

- (id) init {
	self = [super init];
	if (self != nil) {
		currentBigImage = nil;
		currentImages = nil;
		
		imageKit = [[AKImageKit alloc] init];
	}
	return self;
}

- (IBAction)combine:(id)sender
{
	NSString*	dirPath = [dirPathTextField stringValue];
	if (!dirPath) {
		return;
	}
	
	NSFileManager*	fileManager = [NSFileManager defaultManager];
	
	// Check if the path exist and is a dir
	BOOL isDir;
	if (NO == [fileManager fileExistsAtPath:dirPath 
								isDirectory:&isDir]) 
	{
		[logTextField setStringValue:@"No such path!!"];
		return;
	} else if (NO == isDir) {
		[logTextField setStringValue:@"Not a directory!!"];
		return;
	}
	
	// Load all pngs in the directory into the currentImages
	NSDirectoryEnumerator *dirEnum =
		[fileManager enumeratorAtPath:dirPath];
	
	NSMutableArray* images = [NSMutableArray array];
	NSString *fileName;
	
	while (fileName = [dirEnum nextObject]) {
		if ([[fileName pathExtension] isEqualToString: @"png"]) {
			[images addObject:[[NSImage alloc] initWithContentsOfFile:
				[dirPath stringByAppendingPathComponent:fileName]]];
		}
	}
	
	[logTextField setStringValue:
		[NSString stringWithFormat:@"%d images have been created!", [images count]]];
	currentImages = [images copy];
	
	// Get the size of the bigImage
	NSImage* sampleImage = [currentImages objectAtIndex:0];
	NSSize	 imageSize = [sampleImage size];
	unsigned imageNumber = [currentImages count];
	
	NSRect bigImageRect;
	bigImageRect.origin = NSZeroPoint;
	bigImageRect.size = NSMakeSize(imageSize.width*imageNumber, imageSize.height);
	
	NSImage* bigImage; 
	
	// To accumulate the images
	if ([accumulate intValue] && currentBigImage) {
		bigImage = currentBigImage;		
	} else {
		bigImage = [[NSImage alloc] initWithSize:bigImageRect.size];
	}
	
	// Get the fraction value
	float fraction = [alphaTextField floatValue];
	if (fraction > 1.0) {
		fraction = 1.0;
	} else if (fraction < 0.0) {
		fraction = 0.0;
	}
	
	// Draw to the bigImage
	[bigImage lockFocus];
	
	unsigned int index;
	NSRect	drawingRect = NSMakeRect(0.0, 0.0, imageSize.width, imageSize.height);
	NSRect	imageRect   = drawingRect;
	for(index = 0; index < imageNumber; index += 1)
	{
		NSImage*	aImage = [currentImages objectAtIndex:index];
		[aImage drawInRect:drawingRect 
				  fromRect:imageRect 
				 operation:NSCompositeSourceOver 
				  fraction:fraction];
		drawingRect.origin.x += imageSize.width;
	}
	
	[bigImage unlockFocus];
	
	// Use the previewView to draw the image in the current context.
	[previewView setImageToDraw:bigImage];
	[previewView setNeedsDisplay:YES];

	currentBigImage = [bigImage retain];
	[bigImage release];
	

	// Display the big image size
	[widthTextField setStringValue:[NSString stringWithFormat:@"%f", bigImageRect.size.width]];
	[heightTextField setStringValue:[NSString stringWithFormat:@"%f", bigImageRect.size.height]];
	
	// Set the slider's value
	[sizeSlider setMaxValue:bigImageRect.size.width];
	[sizeSlider setMinValue:0.0];
	NSRect bounds = [previewView bounds];
	[sizeSlider setFloatValue:bounds.size.width];
}

- (IBAction)save:(id)sender
{
	NSString*	savePath = [savePathTextField stringValue];
	if ([NSKeyedArchiver archiveRootObject:currentBigImage toFile:savePath]) {
		[logTextField setStringValue:@"save successfully!!"];
	} else {
		[logTextField setStringValue:@"save failed!!"];
	}
}

- (IBAction)goThrough:(id)sender
{
	NSString*	dirPath = [dirPathTextField stringValue];
	if (!dirPath) {
		return;
	}
	
	NSFileManager*	fileManager = [NSFileManager defaultManager];
	
	// Check if the path exist and is a dir
	BOOL isDir;
	if (NO == [fileManager fileExistsAtPath:dirPath 
								isDirectory:&isDir]) 
	{
		[logTextField setStringValue:@"No such path!!"];
		return;
	} else if (NO == isDir) {
		[logTextField setStringValue:@"Not a directory!!"];
		return;
	}	
	
	[self goThroughWithDirectory:dirPath];
}

- (void)goThroughWithDirectory:(NSString*)dirPath
{
	BOOL isDir;
	NSFileManager*	fileManager = [NSFileManager defaultManager];
	
	NSDirectoryEnumerator *dirEnum = [fileManager enumeratorAtPath:dirPath];
	
	if (!fileManager) {
		return;
	}
	
	NSString *fileName;
	NSString *fullPath;
	
	// If there is any sub-directory, go through it too
	while (fileName = [dirEnum nextObject]) {
		fullPath = [dirPath stringByAppendingPathComponent:fileName];
		[fileManager fileExistsAtPath:fullPath isDirectory:&isDir];
		
		if (isDir) {
			// Recursive call!!
			[self goThroughWithDirectory:fullPath];
		}
	}
	
	// Use the imageKit to collect images in the directory. Return if there's no image in it
	if (0 == [imageKit loadImagesFromDirectory:dirPath withType:@"png"])
	{
		return;
	}
	
	if (![imageKit combineImagesToNewCombination]) {
		return;
	}
	
	[imageKit setCurrentImage:nil];
	
	// Then combine them to one "big" image
	[imageKit drawNewCombinationToCurrentImageWithOperation:NSCompositeSourceOver
												   fraction:1.1];
		
	// Obtain the fullSavePath: dirPath = ..../xxx/    fullSavePath = ...../xxx.aki
	NSString* saveFileName = [[dirPath pathComponents] lastObject];
	NSString* fullSavePath = [[dirPath stringByDeletingLastPathComponent] stringByAppendingPathComponent:[saveFileName stringByAppendingPathExtension:@"aki"]];
	
	// Save the "big" image
	[imageKit saveCurrentImageToPath:fullSavePath];
}

- (IBAction)loadToPreview:(id)sender
{
	NSString* filePath = [dirPathTextField stringValue];
	NSImage* imageToDraw = [NSKeyedUnarchiver unarchiveObjectWithFile:filePath];
	if (!imageToDraw) {
		return;
	}
	
	// Use the previewView to draw the image in the current context.
	[previewView setImageToDraw:imageToDraw];
	[previewView setNeedsDisplay:YES];
	
	// Set the slider's value
	NSSize imageSize = [imageToDraw size];
	[sizeSlider setMaxValue:imageSize.width];
	[sizeSlider setMinValue:0.0];
	NSRect bounds = [previewView bounds];
	[sizeSlider setFloatValue:bounds.size.width];
	
	// Set the width and height field
	[widthTextField setFloatValue:imageSize.width];
	[heightTextField setFloatValue:imageSize.height];
}

- (IBAction)goAndBind:(id)sender
{
	NSString* dirPath = [dirPathTextField stringValue];
	
	NSDirectoryEnumerator *dirEnum = [[NSFileManager defaultManager] enumeratorAtPath:dirPath];
	
	if (!dirEnum) {
		return;
	}
	
	NSString *fileName;
	NSString *fullPath;
	
	NSMutableArray* normalImages= [NSMutableArray array];
	NSMutableArray*	reflectionImages = [NSMutableArray array];
	NSMutableArray*	imageNames = [NSMutableArray array];
	
	// Assume the even number is normal image
	// and odd number is reflection
	// Add them acorrdingly to two arrays
	int i;
	for (i = 0; fileName = [dirEnum nextObject]; ++i) {
		fullPath = [dirPath stringByAppendingPathComponent:fileName];
		NSImage* anImage = [NSKeyedUnarchiver unarchiveObjectWithFile:fullPath];
		
		// Reflection
		if (0 == i % 2) {
			NSRange stringRange = [fileName rangeOfString:@"normal"];
			NSString* aFileName = [[fileName substringToIndex:(stringRange.location-1)] stringByAppendingPathExtension:@"akb"];
			NSString* saveImageName = [[dirPath stringByDeletingLastPathComponent] stringByAppendingPathComponent:aFileName];
			NSLog(@"imageName:%@", saveImageName);
			[imageNames addObject:saveImageName];
			[reflectionImages addObject:anImage];
		// Normal
		} else {
			[normalImages addObject:anImage];
		}
	}	
	
	// Check if the numbers of normal and reflection images are same
	unsigned int imageCount = [normalImages count];
	if (imageCount != [reflectionImages count]) {
		[logTextField setStringValue:@"numbers of images are different!"];
	}
	
	// Combined each pair of normal and reflection images
	// Then archive it
	for (i = 0; i < imageCount; ++i) {
		NSImage* newImage = [imageKit combineImage:[reflectionImages objectAtIndex:i]
										 withImage:[normalImages objectAtIndex:i]
										 operation:NSCompositeSourceOver
										  fraction:0.4];
		
		[NSKeyedArchiver archiveRootObject:newImage toFile:[imageNames objectAtIndex:i]];
	}
}

- (NSArray*)currentImages
{
	return currentImages;
}

- (void) dealloc {
	[currentBigImage release];
	[currentImages release];
	[super dealloc];
}

@end
